<template>
  <div class="map-core map-core-frame">
    <iframe ref="iframeRef" :src="mapCore" class="map-container" @load="onLoad"></iframe>
    <slot v-if="ready" v-bind="scope" />
  </div>
</template>

<script>
import { useFullscreen } from '@vueuse/core';
import { ref, shallowRef } from 'vue';
import mapCore from './map.html?url';

export default {
  name: 'map-core-frame',
  emits: ['ready'],
  props: {
    mapOptions: { type: [Object, Function], default: () => ({}) },
  },
  setup() {
    const ready = ref(false);
    const scope = shallowRef({});
    return { ready, scope, mapCore };
  },
  unmounted() {
    this.destroy();
  },
  methods: {
    onLoad() {
      const iframeRef = this.$refs.iframeRef;
      this.iframeWin = iframeRef.contentWindow;
      if (this.iframeWin.mapUtils) {
        this.onReady();
      }
      this.iframeWin.onAMapApiLoaded = () => {
        this.onReady();
      };
    },
    onReady() {
      let mapUtils = this.iframeWin.mapUtils;
      let AMap = mapUtils.getAMap();
      let map = mapUtils.getMap(this.mapOptions);
      this.fullscreen = useFullscreen();
      this.$watch(
        () => this.fullscreen.isFullscreen,
        () => {
          let currentZoom = map.getZoom();
          map.setZoom(this.fullscreen.isFullscreen ? ++currentZoom : --currentZoom);
        },
        { immediate: false }
      );
      this.scope = {
        AMap: AMap,
        map: map,
        mapGetter: () => map,
      };
      this.destroy = function () {
        map.destroy();
        map = null;
        AMap = null;
      };
      this.ready = true;
      setTimeout(() => {
        this.$emit('ready', this.scope);
      }, 50);
    },
  },
};
</script>

<style lang="less">
.map-core {
  position: relative;
  width: 100%;
  height: 100%;
  .map-container {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    border: none;
    overflow: hidden;
    transition: opacity ease 1s;
  }
  .amap-logo,
  .amap-copyright {
    display: none !important;
  }
}
</style>
